package com.jiangyifen.robot.sdk;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jiangyifen.robot.sdk.event.HumanSentenceCompleteEvent;
import com.jiangyifen.robot.sdk.event.HumanSilenceEvent;
import com.jiangyifen.robot.sdk.event.HumanSpeakingByteStreamEvent;
import com.jiangyifen.robot.sdk.event.HumanSpeakingEvent;
import com.jiangyifen.robot.sdk.event.Event;
import com.jiangyifen.robot.sdk.event.RobotSayNodeEvent;
import com.jiangyifen.robot.sdk.event.RobotSentenceCompleteEvent;
import com.jiangyifen.robot.sdk.event.RobotSpeakingEvent;
import com.jiangyifen.robot.sdk.event.SipCalleePickupEvent;
import com.jiangyifen.robot.sdk.event.SipErrorEvent;
import com.jiangyifen.robot.sdk.event.SipIncomingCallEvent;
import com.jiangyifen.robot.sdk.event.SipRegisterFailedEvent;
import com.jiangyifen.robot.sdk.event.SipRegisterSuccessfulEvent;
import com.jiangyifen.robot.sdk.event.SipRegisteringEvent;
import com.jiangyifen.robot.sdk.event.SipRemoteHangupEvent;
import com.jiangyifen.robot.sdk.event.SipRingingEvent;
import com.jiangyifen.robot.sdk.listener.RobotEventListener;
import com.jiangyifen.robot.sdk.response.BaseResponse;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class RobotSdkClientHandler extends SimpleChannelInboundHandler<String> {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private RobotEventListener listener;

	public RobotSdkClientHandler(RobotEventListener listener) {
		this.listener = listener;
	}

	@Override
	public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
		if (StringUtils.isBlank(msg)) {
			logger.error("msg is blank");
			return;
		}

		if ("PING".equals(msg)) {
			// 处理 心跳
			ctx.writeAndFlush("PONG\r\n");
		} else if (msg.contains("event")) {
			// 处理 event
			// 调用client的onXXXEvent(event)
			fireSdkEvent(msg);
		} else if (msg.contains("errCode")) {
			// 处理 response
			handleResponse(msg);
		} else {
			logger.error("unknow msg from server {}", msg);
		}

	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		logger.error(cause.getMessage(), cause);
		ctx.close();
	}

	@SuppressWarnings("unchecked")
	private void handleResponse(String responseString) {
		JSONObject response = JSON.parseObject(responseString);
		String id = response.getString("id");
		if (id == null) {
			return;
		}
		SyncContext<?> syncContext = ShareData.syncContextMap.get(id);
		if (syncContext == null) {
			return;
		}
		synchronized (syncContext) {
			syncContext.setResponse(JSON.parseObject(responseString, BaseResponse.class));
			syncContext.notify();
		}
	}

	private void fireSdkEvent(String eventString) {

		JSONObject json = JSON.parseObject(eventString);
		String eventName = json.getString("event");
		if (Event.humanSentenceCompleteEvent.equals(eventName)) {
			HumanSentenceCompleteEvent event = JSON.parseObject(eventString, HumanSentenceCompleteEvent.class);
			listener.onHumanSentenceComplete(event);
		} else if (Event.humanSilenceEvent.equals(eventName)) {
			HumanSilenceEvent event = JSON.parseObject(eventString, HumanSilenceEvent.class);
			listener.onHumanSilence(event);
		} else if (Event.humanSpeakingByteStreamEvent.equals(eventName)) {
			HumanSpeakingByteStreamEvent event = JSON.parseObject(eventString, HumanSpeakingByteStreamEvent.class);
			listener.onHumanSpeakingByteStreamStream(event);
		} else if (Event.humanSpeakingEvent.equals(eventName)) {
			HumanSpeakingEvent event = JSON.parseObject(eventString, HumanSpeakingEvent.class);
			listener.onHumanSpeaking(event);
		} else if (Event.robotSayNodeEvent.equals(eventName)) {
			RobotSayNodeEvent event = JSON.parseObject(eventString, RobotSayNodeEvent.class);
			listener.onRobotSayNode(event);
		} else if (Event.robotSentenceCompleteEvent.equals(eventName)) {
			RobotSentenceCompleteEvent event = JSON.parseObject(eventString, RobotSentenceCompleteEvent.class);
			listener.onRobotSentenceComplete(event);
		} else if (Event.robotSpeakingEvent.equals(eventName)) {
			RobotSpeakingEvent event = JSON.parseObject(eventString, RobotSpeakingEvent.class);
			listener.onRobotSpeaking(event);
		} else if (Event.sipRegistering.equals(eventName)) {
			SipRegisteringEvent event = JSON.parseObject(eventString, SipRegisteringEvent.class);
			listener.onSipRegistering(event);
		} else if (Event.sipRegisterSuccessful.equals(eventName)) {
			SipRegisterSuccessfulEvent event = JSON.parseObject(eventString, SipRegisterSuccessfulEvent.class);
			listener.onSipRegisterSuccessful(event);
		} else if (Event.sipRegisterFailed.equals(eventName)) {
			SipRegisterFailedEvent event = JSON.parseObject(eventString, SipRegisterFailedEvent.class);
			listener.onSipRegisterFailed(event);
		} else if (Event.sipRinging.equals(eventName)) {
			SipRingingEvent event = JSON.parseObject(eventString, SipRingingEvent.class);
			listener.onSipRinging(event);
		} else if (Event.sipIncomingCall.equals(eventName)) {
			SipIncomingCallEvent event = JSON.parseObject(eventString, SipIncomingCallEvent.class);
			listener.onSipIncomingCall(event);
		} else if (Event.sipCalleePickup.equals(eventName)) {
			SipCalleePickupEvent event = JSON.parseObject(eventString, SipCalleePickupEvent.class);
			listener.onSipCalleePickup(event);
		} else if (Event.sipRemoteHangup.equals(eventName)) {
			SipRemoteHangupEvent event = JSON.parseObject(eventString, SipRemoteHangupEvent.class);
			listener.onSipRemoteHangup(event);
		} else if (Event.sipError.equals(eventName)) {
			SipErrorEvent event = JSON.parseObject(eventString, SipErrorEvent.class);
			listener.onSipError(event);
		} else {
			logger.error("unknow event: {}.", eventName);
		}

	}
}
